iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
1
Modern Web

學習 vue 30天系列 第 16

Vue 16 進階模板語法介紹 (2) - v-for 使用細節

  • 分享至 

  • xImage
  •  

v-for 使用細節

v-for 可以用陣列或是物件帶入,比較特別的是用物件帶入的話,是用屬性來做索引。

<h4>陣列與物件的迴圈</h4>
// 陣列的索引是一般我們熟知的 0 到 陣列長度
<ul>
    <li v-for="(item, key) in arrayData">
        {{ key }} - {{ item.name }} {{ item.age }} 歲
    </li>
</ul>

// 物件的索引是由『屬性』來擔當
<ul>
    <li v-for="(item,key) in objectData">
        {{key}} - {{item.name}} {{item,age}} 歲
    </li>
</ul>

data: {
    arrayData: [{
        name: '小明',
        age: 16
    }, {
        name: '漂亮阿姨',
        age: 24
    }, {
        name: '杰倫',
        age: 20
    }],
    objectData: {
        ming: {
            name: '小明',
            age: 16
        },
        auntie: {
            name: '漂亮阿姨',
            age: 24
        },
        jay: {
            name: '杰倫',
            age: 20
        }
    },
},

https://ithelp.ithome.com.tw/upload/images/20190917/20109609NT24lDzUb0.png

Key

vue 在切換畫面是部分置換,如果有 textbox 這類的 DOM 元素就無法置換,因為替換 DOM 元素是是快速置換,所以這裡的 textbox 不會變動。

<h4>Key</h4>
<ul>
    <li v-for="(item, key) in arrayData">
        {{ key }} - {{ item.name }} {{ item.age }} 歲 
        <input type="text">
    </li>
</ul>
<button class="btn btn-outline-primary">反轉陣列</button>



methods: {
    reverseArray: function() {
        this.arrayData.reverse()
        console.log(this.arrayData)
    },
}

那要避免這個問題可以用 key ,這個 key 很像我們人的 ID ,要用無重複的值來當 key

<h4>Key</h4>
<ul>
    <li v-for="(item, key) in arrayData" :key="item.age">
        {{ key }} - {{ item.name }} {{ item.age }} 歲 
        <input type="text">
    </li>
</ul>
<button class="btn btn-outline-primary">反轉陣列</button>



methods: {
    reverseArray: function() {
        this.arrayData.reverse()
        console.log(this.arrayData)
    },
}

Filter

過濾也很常搭配 v-for 來使用,我們可以用 textbox 來過濾出我們要的資料。

<h4>Filter</h4>
<input type="text" class="form-control" v-model="filterText">
<ul>
    <li v-for="(item, key) in filterArray" :key="item.age">
        {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
</ul>

methods: {
    filterData: function() {
        // 這邊會需要把 this 存到變數中,因為在 for 迴圈中 this 會被替換掉。
        // 這邊的 this 是指可以取用 vue 裡的 data
        let vm = this;
        console.log(vm);
        // filter() 會回傳一個陣列,其條件是 return 後方為 true 的物件,很適合用在搜尋符合條件的資料。
        vm.filterArray = vm.arrayData.filter(function(item) {
            // vm.filterText 是我們當下搜尋的值
            // item.name 是每個 item 的名稱
            // item.name.match(vm.filterText) 用每一筆去跟搜尋的值判斷是否相同,相同就會是 true
            console.log(vm.filterText, item.name, item.name.match(vm.filterText))
            return item.name.match(vm.filterText);
        });
    }
}

不能運作的狀況

第一個狀況:直接修改陣列長度
在原本 JS 如果我們對陣列的長度改為 0 的話,這個陣列內容會被刪除,但是我們在 vue.js 是無法操作的。

<h4>不能運作的狀況</h4>
<button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
<ul>
    <li v-for="(item, key) in arrayData" :key="item.age">
        {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
</ul>

cantWork: function() {
    this.arrayData.length = 0;
    console.log(this.arrayData);
}

在 console 或是 devtool 裡可以看到陣列長度是 0,但畫面上並沒有消除。
https://ithelp.ithome.com.tw/upload/images/20190917/20109609H8b2WtCRrb.png
https://ithelp.ithome.com.tw/upload/images/20190917/20109609dJap6FMEWh.png
https://ithelp.ithome.com.tw/upload/images/20190917/20109609EUJ5kx1m0Z.png

第二個狀況:修改某索引裡的資料
如果想嘗試修改索引 0 的資料是無法成功的。

<h4>不能運作的狀況</h4>
<button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
<ul>
    <li v-for="(item, key) in arrayData" :key="item.age">
        {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
</ul>

cantWork: function() {
    this.arrayData[0] = {
        name: "帥哥",
        age: 23,
    };
    console.log(this.arrayData);
}

由 console 和 devtoole 上值都有改變,但畫面上就是沒有變動,在這裏可以知道我們無法用索引的方式來修改資料。
https://ithelp.ithome.com.tw/upload/images/20190917/20109609H8b2WtCRrb.png
https://ithelp.ithome.com.tw/upload/images/20190917/20109609kGLTGyIKj7.png
https://ithelp.ithome.com.tw/upload/images/20190917/20109609JgB6tXEZDj.png

那我們要修改的話我們必須使用 Vue.set()
使用時機:當我們要操作 vue data 但這份資料並沒有在裡面的時候使用,將資料寫入到 data,讓它可以重新的監控。

<h4>不能運作的狀況</h4>
<button class="btn btn-outline-primary" @click="cantWork">無法運行</button>
<ul>
    <li v-for="(item, key) in arrayData" :key="item.age">
        {{ key }} - {{ item.name }} {{ item.age }} 歲 <input type="text">
    </li>
</ul>

cantWork: function() {
    Vue.set(this.arrayData, 0, {
        name: "帥哥",
        age: 23,
    })
}

Template 的運用

假設我們想讓兩個 tr 為一個群組的話可以用 templatetemplate是不會被打印出來的。

<h4>Template 的運用</h4>
<p>請將兩個 tr 一組使用 v-for</p>
<table class="table">
    <template v-for="item in arrayData">
    <tr>
      <td>{{item.age}}</td>
    </tr>
    <tr>
      <td>{{item.name}}</td>
    </tr>
  </template>
</table>

https://ithelp.ithome.com.tw/upload/images/20190917/20109609bsPZpdwkfe.png

v-for 與 v-if

v-forv-if 同時寫在一個元素時 v-for 會先執行再執行 v-if,所以可以藉由 v-if 來對迴圈做些判斷。

<h4>v-for 與 v-if</h4>
<ul>
    <li v-for="(item, key) in arrayData" v-if="item.age<20">
        {{ key }} - {{ item.name }} {{ item.age }} 歲
    </li>
</ul>

https://ithelp.ithome.com.tw/upload/images/20190917/20109609cNnOBHda4I.png


上一篇
Vue 15 進階模板語法介紹 (1) - 資料細節及動態切換 class name 及 style 多種方法
下一篇
Vue 17 進階模板語法介紹 (3) - v-if 模板判斷
系列文
學習 vue 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言